#include "gd32e23x.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "DevicesSPI.h"


void vSPI0Init(void)
{
    spi_parameter_struct spi_init_struct = {0};

    /* enable GPIOx clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    /* enable SPIx clock */
    rcu_periph_clock_enable(RCU_SPI0);

    /* SPI0 GPIO configuration: SCK/PA5, MISO/PA6, MOSI/PA7 */
    gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);

    /* NSSA/PA0 NSSG/PA1 */
    gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0 | GPIO_PIN_1);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);

    SET_SPI0_NSS_A_HIGH();
    SET_SPI0_NSS_G_HIGH();


    /* SPIx parameter config */
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.device_mode          = SPI_MASTER;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
    spi_init_struct.nss                  = SPI_NSS_SOFT;
    spi_init_struct.prescale             = SPI_PSC_8;
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
    spi_init(SPI0, &spi_init_struct);

    // /* configure SPI1 byte access to FIFO */
    // spi_fifo_access_size_config(SPI1, SPI_BYTE_ACCESS);


    /* SPI enable */
    spi_enable(SPI0);
}

uint8_t ucSPIWriteReadByte(uint32_t uiSpiPeriph, uint8_t ucByte)
{
    while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_TBE));
    spi_i2s_data_transmit(uiSpiPeriph, ucByte);

    while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_RBNE));
    ucByte = spi_i2s_data_receive(uiSpiPeriph);

    return ucByte;
}

int8_t cSPIWriteDatas(uint32_t uiSpiPeriph, uint8_t *pBuffer, int32_t iLength)
{
    int8_t cError = 0;

    if(pBuffer == NULL)
        return -1;

    while((iLength--) > 0)
    {
        while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_TBE));
        spi_i2s_data_transmit(uiSpiPeriph, *pBuffer++);
    }

    return cError;
}

int8_t cSPIReadDatas(uint32_t uiSpiPeriph, uint8_t *pBuffer, int32_t iLength)
{
    int8_t cError = 0;

    if(pBuffer == NULL)
        return -1;

    while((iLength--) > 0)
    {
        while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_TBE));
        spi_i2s_data_transmit(uiSpiPeriph, 0xFFFF);

        while(RESET == spi_i2s_flag_get(uiSpiPeriph, SPI_FLAG_RBNE));
        *pBuffer++ = spi_i2s_data_receive(uiSpiPeriph);
    }

    return cError;
}
